package com.gpframework.module.ctn.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.common.config.GpframeworkConfig;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.module.ctn.domain.GpCtnOrder;
import com.gpframework.module.ctn.domain.GpPackagesInformation;
import com.gpframework.module.ctn.domain.GpReceiptGoods;
import com.gpframework.module.ctn.domain.GpSackInformation;
import com.gpframework.module.ctn.domain.vo.GpCtnOrderExcel;
import com.gpframework.module.ctn.domain.vo.GpCtnOrderVo;
import com.gpframework.module.ctn.domain.vo.GpSupplierSummaryVo;
import com.gpframework.module.ctn.mapper.GpCtnOrderMapper;
import com.gpframework.module.ctn.service.IGpCtnOrderService;
import com.gpframework.module.ctn.service.IGpReceiptGoodsService;
import com.gpframework.module.ctn.service.IGpSackInformationService;
import com.gpframework.module.module.domain.GpDomesticFreightForwarding;
import com.gpframework.module.module.service.IGpDomesticFreightForwardingService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName GpCtnOrder
 * @Author gpframework
 * @Date 2024-01-08
 * @Version 1.0.0
 * @Description 定货柜填写Service业务层处理
 */
@Service
public class GpCtnOrderServiceImpl extends ServiceImpl<GpCtnOrderMapper, GpCtnOrder> implements IGpCtnOrderService {
    @Autowired
    private GpPackagesInformationServiceImpl iGpPackagesInformationService;

    @Autowired
    private IGpReceiptGoodsService iGpReceiptGoodsService;

    @Autowired
    private IGpSackInformationService iGpSackInformationService;


    @Autowired
    private IGpDomesticFreightForwardingService iGpDomesticFreightForwardingService;

    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2024-01-08
     * @Param [lqw]
     * @Return List<GpCtnOrderVo>
     */
    @Override
    public List<GpCtnOrderVo> listVo(QueryWrapper<GpCtnOrder> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2024-01-08
     * @Param [id]
     * @Return GpCtnOrderVo
     */
    @Override
    public GpCtnOrderVo getVoById(Long id) {
        return this.baseMapper.getVo(id);
    }

    @Override
    public List<GpCtnOrderExcel> gpCtnOrderImport(List<GpCtnOrderExcel> excelList, Long brandId, Long storeId) {
        //导入失败的列表

        List<GpCtnOrderExcel> failureList = new ArrayList<>();
        //定货柜填写
        GpCtnOrder gpCtnOrder;

        for (int i = 0; i < excelList.size(); i++) {
            GpCtnOrderExcel excel = excelList.get(i);
            if (StringUtils.isNull(excel)) {
                excel = new GpCtnOrderExcel();
                excel.setSubscript(i+1);
                excel.setMsg("读取数据失败");
                failureList.add(excel);
                continue;
            }

            gpCtnOrder = Convert.convert(new TypeReference<GpCtnOrder>() {}, excel);
            this.save(gpCtnOrder);
        }
        return failureList;
    }

    @Override
    public GpCtnOrderExcel getString(Collection<?> coll, Object ob, InputStream inputStream, String fileName) throws IOException, IllegalAccessException {
        GpCtnOrderExcel gpExcelTemplateUrl = new GpCtnOrderExcel();
        try {

            String filename = StringUtils.encodingFilename(fileName);
            String absoluteFile = StringUtils.getAbsoluteFile(filename);
            FileOutputStream outputStream = new FileOutputStream(absoluteFile);
            int[] mergeColumnIndex = {1,2,3,5,6};
            // 需要从第几行开始合并
            int mergeRowIndex = 4;


            //设置输出流和模板信息
            ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(inputStream)
                    .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex))
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
//            writeSheet.setAutoMergeCell(true);
            //开启自动换行,自动换行表示每次写入一条list数据是都会重新生成一行空行,此选项默认是关闭的,需要提前设置为true
            if (CollectionUtils.isNotEmpty(coll)) {
                //横斜
//                FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
                FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

                //设置自动合并单元格
                excelWriter.fill(coll, fillConfig, writeSheet);
            }

            excelWriter.fill(ob, writeSheet);
            excelWriter.finish();

            gpExcelTemplateUrl.setUrl(GpframeworkConfig.getPath() + filename);
            gpExcelTemplateUrl.setAbsoluteFile(absoluteFile);

            File file1 = new File(absoluteFile);
            FileInputStream file = new FileInputStream(file1);
            Workbook workbook=new XSSFWorkbook(file);
            Sheet sheet = workbook.getSheetAt(0);

            // 获取总行数
            int rowCount = sheet.getPhysicalNumberOfRows();

            // 定义正则表达式模式
            String regex = "-.*"; // 匹配 "-" 后的任意字符

            // 编译正则表达式
            Pattern pattern = Pattern.compile(regex);

            // 从第六行开始处理
            for (int i = 5; i < rowCount; i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    // 对该行中的每个单元格进行处理
                    for (Cell cell : row) {
                        cell.setCellType(CellType.STRING);
                        String cellValue = cell.getStringCellValue();

                        // 使用正则表达式进行匹配
                        Matcher matcher = pattern.matcher(cellValue);
                        if (matcher.find()) {
                            // 找到匹配项，将 "-" 及其后内容替换为空字符串
                            String replacedValue = matcher.replaceAll("");
                            cell.setCellValue(replacedValue);
                        }
                    }
                }
            }

            file.close();

            FileOutputStream outFile = new FileOutputStream(absoluteFile);
            workbook.write(outFile);
            outFile.close();
            workbook.close();


            gpExcelTemplateUrl.setAbsoluteFile(absoluteFile);

            return gpExcelTemplateUrl;
        } catch (FileNotFoundException e) {
            log.error("生成excel错误：" + e);
            return null;
        }
    }


    @Override
    public List<GpSupplierSummaryVo> supplierSummary(QueryWrapper<GpReceiptGoods> lqw) {
        return this.baseMapper.supplierSummary(lqw);
    }


    @Override
    public GpCtnOrderExcel getStringPackSack(Collection<?> coll, Object ob, InputStream inputStream, String fileName) throws IOException, IllegalAccessException {
        GpCtnOrderExcel gpExcelTemplateUrl = new GpCtnOrderExcel();
        try {

            String filename = StringUtils.encodingFilename(fileName);
            String absoluteFile = StringUtils.getAbsoluteFile(filename);
            FileOutputStream outputStream = new FileOutputStream(absoluteFile);
            int[] mergeColumnIndex = {0,1,2,3,4,6,7,8,9,10};
            // 需要从第几行开始合并
            int mergeRowIndex = 1;


            //设置输出流和模板信息
            ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(inputStream)
                    .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex))
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
//            writeSheet.setAutoMergeCell(true);
            //开启自动换行,自动换行表示每次写入一条list数据是都会重新生成一行空行,此选项默认是关闭的,需要提前设置为true
            if (CollectionUtils.isNotEmpty(coll)) {
                //横斜
//                FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
                FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

                //设置自动合并单元格
                excelWriter.fill(coll, fillConfig, writeSheet);
            }

            excelWriter.fill(ob, writeSheet);
            excelWriter.finish();

            gpExcelTemplateUrl.setUrl(GpframeworkConfig.getPath() + filename);
            gpExcelTemplateUrl.setAbsoluteFile(absoluteFile);

            File file1 = new File(absoluteFile);
            FileInputStream file = new FileInputStream(file1);
            Workbook workbook=new XSSFWorkbook(file);
            Sheet sheet = workbook.getSheetAt(0);

            // 获取总行数
            int rowCount = sheet.getPhysicalNumberOfRows();

            // 定义正则表达式模式
            String regex = "-.*"; // 匹配 "-" 后的任意字符

            // 编译正则表达式
            Pattern pattern = Pattern.compile(regex);

            // 从第三行开始处理
            for (int i = 2; i < rowCount; i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    // 对该行中的每个单元格进行处理
                    for (Cell cell : row) {
                        cell.setCellType(CellType.STRING);
                        String cellValue = cell.getStringCellValue();

                        // 使用正则表达式进行匹配
                        Matcher matcher = pattern.matcher(cellValue);
                        if (matcher.find()) {
                            // 找到匹配项，将 "-" 及其后内容替换为空字符串
                            String replacedValue = matcher.replaceAll("");
                            cell.setCellValue(replacedValue);
                        }
                    }
                }
            }

            file.close();

            FileOutputStream outFile = new FileOutputStream(absoluteFile);
            workbook.write(outFile);
            outFile.close();
            workbook.close();


            gpExcelTemplateUrl.setAbsoluteFile(absoluteFile);

            return gpExcelTemplateUrl;
        } catch (FileNotFoundException e) {
            log.error("生成excel错误：" + e);
            return null;
        }
    }






    @Override
    public boolean orderLoadList(List<GpCtnOrder> gpCtnOrderList) {
        if (CollectionUtils.isNotEmpty(gpCtnOrderList)){
            for (int i = 0; i < gpCtnOrderList.size(); i++) {
                GpCtnOrder ctnOrderUpdate = gpCtnOrderList.get(i);
                GpCtnOrder gpCtnOrder = Convert.convert(new TypeReference<GpCtnOrder>() {}, ctnOrderUpdate);
                gpCtnOrder.setLoadedPictures(StringUtils.listTostring(ctnOrderUpdate.getLoadedPictureseAdd()));
                gpCtnOrder.setLoadedVideo(StringUtils.listTostring(ctnOrderUpdate.getLoadedVideoAdd()));

                GpDomesticFreightForwarding gpDomesticFreightForwarding = iGpDomesticFreightForwardingService.getById(ctnOrderUpdate.getDomesticFreightForwardingId());
                if(gpDomesticFreightForwarding !=null){
                    gpCtnOrder.setChineseAgent(gpDomesticFreightForwarding.getChineseAgent());
                }

                this.updateById(gpCtnOrder);
                if (CollectionUtils.isNotEmpty(ctnOrderUpdate.getGpPackagesInformationList())){
                    //绑定打包信息
                    this.savePackagesInformations(ctnOrderUpdate);
                }
                if (CollectionUtils.isNotEmpty(ctnOrderUpdate.getGpSackInformationList())){
                    //绑定散货信息
                    this.saveSackInformation(ctnOrderUpdate);
                }

            }
        }
        return true;
    }

    private void saveSackInformation(GpCtnOrder ctnOrderUpdate) {
        ArrayList<GpSackInformation> gpSackInformationList = new ArrayList<>();
        List<GpSackInformation> list = ctnOrderUpdate.getGpSackInformationList();
        for (GpSackInformation gpSackInformation : list) {
            //保存订单信息
            GpReceiptGoods gpReceiptGoods = iGpReceiptGoodsService.getById(gpSackInformation.getReceiptId());
            //装柜操作
            gpSackInformation.setCtnOrderId(ctnOrderUpdate.getId());

            gpSackInformation.setCustomer(gpReceiptGoods.getCustomer());
            gpSackInformation.setCustomerTel(gpReceiptGoods.getCustomerTel());
            gpSackInformation.setSupplier(gpReceiptGoods.getSupplier());
            gpSackInformation.setSupplierTel(gpReceiptGoods.getSupplierTel());
            gpSackInformation.setUnit(gpReceiptGoods.getUnit());
            gpSackInformation.setReceiptNo(gpReceiptGoods.getReceiptNo());
            gpSackInformation.setHoldOrNot(gpReceiptGoods.getHoldOrNot());
            gpSackInformation.setCbm(gpReceiptGoods.getCbm());
            gpSackInformation.setRemarks(gpReceiptGoods.getRemarks());
            gpSackInformationList.add(gpSackInformation);
        }
        iGpSackInformationService.updateBatchById(gpSackInformationList);
    }

    private void savePackagesInformations(GpCtnOrder ctnOrderUpdate) {
        ArrayList<GpPackagesInformation> packagesInformationList = new ArrayList<>();
        List<GpPackagesInformation> list = ctnOrderUpdate.getGpPackagesInformationList();
        for (GpPackagesInformation gpPackagesInformation : list) {
            //保存订单信息
            GpReceiptGoods gpReceiptGoods = iGpReceiptGoodsService.getById(gpPackagesInformation.getReceiptId());
            //装柜操作
            gpPackagesInformation.setCtnOrderId(ctnOrderUpdate.getId());

            gpPackagesInformation.setCustomer(gpReceiptGoods.getCustomer());
            gpPackagesInformation.setCustomerTel(gpReceiptGoods.getCustomerTel());
            gpPackagesInformation.setSupplier(gpReceiptGoods.getSupplier());
            gpPackagesInformation.setSupplierTel(gpReceiptGoods.getSupplierTel());
            gpPackagesInformation.setUnit(gpReceiptGoods.getUnit());
            gpPackagesInformation.setReceiptNo(gpReceiptGoods.getReceiptNo());
            gpPackagesInformation.setHoldOrNot(gpReceiptGoods.getHoldOrNot());
            gpPackagesInformation.setCbm(gpReceiptGoods.getCbm());
            gpPackagesInformation.setRemarks(gpReceiptGoods.getRemarks());
            packagesInformationList.add(gpPackagesInformation);
        }
        iGpPackagesInformationService.updateBatchById(packagesInformationList);
    }

}
